package net.fdukedom.epicurus.plugin;

import net.fdukedom.epicurus.domain.entity.Plugin;
import net.fdukedom.epicurus.domain.util.PluginHelper;
import net.fdukedom.epicurus.tools.logging.Logger;
import net.fdukedom.epicurus.tools.logging.WriterId;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;

import org.jdom.input.SAXBuilder;
import org.jdom.Document;
import org.jdom.JDOMException;

/**
 * @author Dmitry Kochelaev
 */
public class FilePluginLoader extends AbstractPluginLoader {

    /**
     * Plug-ins' descriptions folder.
     */
    private File pluginFolder;

    private Logger logger = Logger.getInstance(WriterId.PLUGIN_LOADER);

    /**
     * Creates plug-in loader for specified folder.
     *
     * @param pluginFolder folder with plug-ins' descriptions
     *
     * @throws java.io.FileNotFoundException if file doesn't exist or isn't folder
     */
    public FilePluginLoader(File pluginFolder) throws FileNotFoundException {
        if (!pluginFolder.exists() || !pluginFolder.isDirectory()) {
            throw new FileNotFoundException(pluginFolder.getName());
        }
        this.pluginFolder = pluginFolder;
    }

    public List<Plugin> loadPlugins() {
        List<Plugin> plugins = new ArrayList<Plugin>();
        File[] descriptions = pluginFolder.listFiles(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith("-pd.xml");
            }
        });
        Map<String, Plugin> registredPlugins = PluginHelper.getInstance().loadPluginsMap();
        SAXBuilder builder = new SAXBuilder();
        for (File descriptionFile : descriptions) {
            try {
                Document description = builder.build(descriptionFile);
                Plugin plugin = parsePlugin(description.getRootElement(), registredPlugins);
                plugins.add(plugin);
            } catch (JDOMException e) {
                logger.logError("Plug-in loading exception. Plug-in file: " + descriptionFile.getName() + ". Exception message: " + e.getMessage());
            } catch (IOException e) {
                logger.logError("Plug-in loading exception. Plug-in file: " + descriptionFile.getName() + ". Exception message: " + e.getMessage());
            } catch (PluginParsingException e) {
                logger.logError("Plug-in loading exception. Plug-in file: " + descriptionFile.getName() + ". Exception message: " + e.getMessage());
            }
        }
        return plugins;
    }
}
